#include "stdafx.h"
#include "gdiplustest2.h"
#include "gdiplustest2Doc.h"
#include "MyUtil.h"
#include <gdiplus.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNCREATE(Cgdiplustest2Doc, CDocument)

BEGIN_MESSAGE_MAP(Cgdiplustest2Doc, CDocument)
    ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
    ON_COMMAND(ID_FILE_OPENFOLDER, &Cgdiplustest2Doc::OnFileOpenfolder)
END_MESSAGE_MAP()

Cgdiplustest2Doc::Cgdiplustest2Doc()
{
    myImage = 0;
}

Cgdiplustest2Doc::~Cgdiplustest2Doc()
{
    //delete myImage; myImage = 0;
}

BOOL Cgdiplustest2Doc::OnNewDocument()
{
    if (!CDocument::OnNewDocument())
        return FALSE;
    return TRUE;
}

void Cgdiplustest2Doc::OnFileOpen()
{
    static TCHAR szFilters[] =
      _T("graphic files (*.jpg;*.bmp;*.png;*.gif;*.tif)|*.jpg; *.bmp; *.png; *.gif; *.tif|JPEG (*.jpg)|*.jpg|BMP (*.bmp)|*.bmp|PNG (*.png)|*.png|GIF (*.gif)|*.gif|TIFF (*.tif)|*.tif|All Files (*.*)|*.*||");

   CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, szFilters);
   
    if( fileDlg.DoModal() == IDOK ) {
        CString pathName = fileDlg.GetPathName();

        delete myImage;
        myImage = Gdiplus::Image::FromFile((const wchar_t *)pathName, TRUE);
    }
    UpdateAllViews(NULL);
}

bool ShowBrowseForFolder(TCHAR *folderName_return)
{
    ASSERT(folderName_return);

    bool rv = true;
    BROWSEINFO bi;
    memset(&bi, 0, sizeof bi);

    ITEMIDLIST* piid = ::SHBrowseForFolder(&bi);
    if (!(piid && ::SHGetPathFromIDList(piid, folderName_return))) {
        rv = false;
    }
    if (piid) {
        LPMALLOC lpMalloc;
        VERIFY(::SHGetMalloc(&lpMalloc) == NOERROR);
        lpMalloc->Free(piid);
        lpMalloc->Release();
    }

    return rv;
}

static SIZE ThumbSizeOrientationCalc(const SIZE & imageSize, const SIZE & thumbnailSize)
{
    SIZE rv(thumbnailSize);
    if ((0 == (imageSize.cx / imageSize.cy)) !=
        (0 == (thumbnailSize.cx / thumbnailSize.cy))) {
        rv.cx = thumbnailSize.cy;
        rv.cy = thumbnailSize.cx;
    }
    return rv;
}

static Gdiplus::Image * BitmapResample_KeepAspectRatio(Gdiplus::Image * bm, const SIZE & size)
{
    SIZE bmSize;
    bmSize.cx = bm->GetWidth();
    bmSize.cy = bm->GetHeight();

    SIZE newSize = ThumbSizeOrientationCalc(bmSize, size);
    if ((float)newSize.cx / newSize.cy < (float)bmSize.cx / bmSize.cy) {
        newSize.cy = bmSize.cy * newSize.cx / bmSize.cx;
        if (0 == newSize.cy) {
            newSize.cy = 1;
        }
    } else {
        newSize.cx = bmSize.cx * newSize.cy / bmSize.cy;
        if (0 == newSize.cx) {
            newSize.cx = 1;
        }
    }
    Gdiplus::Image * newBM = ::new Gdiplus::Bitmap(newSize.cx, newSize.cy);
    Gdiplus::Graphics g(newBM);
    g.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
    g.DrawImage(bm, 0, 0, newSize.cx, newSize.cy);
    return newBM;
}

static SIZE thumbSize;

static void ScanDir1(TCHAR *folderName, bool bRecursive, int nRecurse)
{
    TCHAR s[MAX_PATH];
    TCHAR subDir[MAX_PATH];
    TCHAR filePath[MAX_PATH];
    _tcscpy_s<sizeof s/sizeof s[0]>(s, folderName);
    _tcscat_s<sizeof s/sizeof s[0]>(s, _T("\\*"));

    WIN32_FIND_DATA fileData;
    HANDLE hList = FindFirstFile(s, &fileData);
    if (hList != INVALID_HANDLE_VALUE) { 
        bool fFinished = false;
        do {
            //dprintf(_T(" %s %d\n"), fileData.cFileName, fileData.dwFileAttributes);
            if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if ((_tcscmp(fileData.cFileName, _T(".")) != 0) &&
                    (_tcscmp(fileData.cFileName, _T("..")) != 0)) {
                    dprintf(_T("%s\n"), fileData.cFileName);

                    if (bRecursive || 0 == nRecurse) {
                        _stprintf_s<sizeof subDir/sizeof subDir[0]>(subDir, _T("%s\\%s"), folderName, fileData.cFileName);
                        ScanDir1(subDir, bRecursive, nRecurse + 1);
                    }
                }
            } else {
                _stprintf_s<sizeof filePath/sizeof filePath[0]>(filePath, _T("%s\\%s"), folderName, fileData.cFileName);
                dprintf(_T("  %s "), filePath);
                Gdiplus::Image *pImage = Gdiplus::Image::FromFile(filePath, TRUE);
                ASSERT(pImage);
                int w = pImage->GetWidth();
                int h = pImage->GetHeight();
                if (0 < w) {
                    dprintf(_T("read success (%d, %d)\n"), w, h);
                    Gdiplus::Image *thumbImage = BitmapResample_KeepAspectRatio(pImage, thumbSize);
                    ::delete thumbImage; thumbImage = 0;
                } else {
                    dprintf(_T("read failed\n"));
                }
                delete pImage; pImage = 0;
            }

            if (!FindNextFile(hList, &fileData)) {
                if (GetLastError() == ERROR_NO_MORE_FILES) {
                    fFinished = TRUE;
                }
            }
        } while (!fFinished);
    }
    FindClose(hList);
}

static void ScanDir(TCHAR *folderName, bool bRecursive)
{
    return ScanDir1(folderName, bRecursive, 0);
}

void Cgdiplustest2Doc::OnFileOpenfolder()
{
    TCHAR folderName[MAX_PATH];
    if (ShowBrowseForFolder(folderName)) {
        dprintf(_T("OnFileOpenFolder folderName=%s\n"), folderName);
        thumbSize.cx = 120;
        thumbSize.cy = (LONG)(120 * 1.41f);
        ScanDir(folderName, true);
    }
}

void Cgdiplustest2Doc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
    }
    else
    {
    }
}

#ifdef _DEBUG
void Cgdiplustest2Doc::AssertValid() const
{
    CDocument::AssertValid();
}

void Cgdiplustest2Doc::Dump(CDumpContext& dc) const
{
    CDocument::Dump(dc);
}
#endif //_DEBUG

